﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ColliderCal : MonoBehaviour, ISubPhysicsCollider
{
    private List<CollideInfo> collisionInfo = new List<CollideInfo>();

    private TerrianQuadTree.QuadNode thisNode;
    public Chunk belongChunk { get; set; }
    public void SetNode(TerrianQuadTree.QuadNode node)
    {
        this.thisNode = node;
    }
    void Start()
    {

    }
    void Update()
    {
    }

    void OnCollisionEnter2D(Collision2D collision)
    {
        foreach (Vector2 p in GetcontactPos(collision))
        {
            ISubPhysicsCollider rightGo = collision.collider.GetComponent<ISubPhysicsCollider>();
            var rightInfos = rightGo.GetCollideInfos(collision);
            if (rightGo == null)
            {
                Debug.LogWarning("Terrian : Collision with non-standard object");
            }
            foreach(var x in rightInfos)
            {
                var args = new CollisionArgs();
                List<uint> ids = TerrianManager.Instance.PosMatch(p, thisNode);
                foreach(var id in ids)
                {
                    args.StressedID = id;
                    args.StressedState = (ElementState)TerrianManager.Instance.GetElem(id);
                    args.StressedSystem = BelongingSystem.Ground;
                    args.StressingID = x.Identity.Item1;
                    args.StressingState = x.Identity.Item3;
                    args.StressingSystem = x.Identity.Item2;
                    CollisionForceInfo forceInfo = new CollisionForceInfo();
                    forceInfo.WorldPos = x.CollidePositionInWorld;
                    forceInfo.Force = x.Force;
                    args.Info = forceInfo;
                    TerrianManager.colliderInfoList.Add(args);
                }
            }
        }
    }

    public static Vector2 GetForce(Collision2D collision)
    {
        Vector2 force = Vector2.zero;
        foreach (ContactPoint2D point in collision.contacts)
        {
            force += point.normal * point.normalImpulse / Time.fixedDeltaTime;
        }
        return force;
    }

    public static List<Vector2> GetcontactPos(Collision2D collision)
    {
        List<Vector2> ans = new List<Vector2>();
        foreach (var c in collision.contacts)
        {
            ans.Add(c.point);
        }
        return ans;
    }


    public Tuple<uint, BelongingSystem, ElementState> GetObjectInfo()
    {
        throw new NotImplementedException();
    }

    public List<CollideInfo> GetCollideInfos(Collision2D obj)
    {
        List<CollideInfo> ans = new List<CollideInfo>();
        var collisionPoss = GetcontactPos(obj);
        Vector2 compositionForceSlice = GetForce(obj)/collisionPoss.Count;
        foreach (Vector2 p in collisionPoss)
        {
            var ids = TerrianManager.Instance.PosMatch(p, this.thisNode);
            foreach(var id in ids)
            {
                var tryGetCollision = ans.Find(x => x.Identity.Item1 == id);
                ElementState elem = (ElementState)TerrianManager.Instance.GetElem(id);
                if (tryGetCollision == null)
                {
                    ans.Add(new CollideInfo(new Tuple<uint, BelongingSystem, ElementState>(id, BelongingSystem.Ground, elem), p, compositionForceSlice));
                }
                else
                {
                    tryGetCollision.Force += compositionForceSlice;
                }
            }
        }
        return ans;
    }
}
